package com.ganzalang.gmall.concurrentart.leetcode.producerconsumer;

import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.security.RunAs;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;

@Slf4j
public class Solution1 {

    private static Queue<Object> queue = new LinkedList<>();
    private static final Integer MAX_SIZE = 10;
    static Random random = new Random();


    static class Producer implements Runnable{

        @Override
        public void run() {
            synchronized (queue) {
                // 队列满了，则阻塞
                while (queue.size() >= MAX_SIZE) {
                    try {
                        log.info("[Producer]--Queue fulled!");
                        queue.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }

                int value = random.nextInt(100);
                // 入队
                queue.offer(value);
                log.info("[Producer]--Produce element {}", value);
                // 唤醒其他线程
                queue.notifyAll();
            }
        }

    }

    static class Consumer implements Runnable {

        @SneakyThrows
        @Override
        public void run() {
            // 循环消费
            while (true) {
                Thread.sleep(500L);

                synchronized (queue) {
                    while (queue.size() <= 0) {
                        try {
                            log.info("[Consumer]--Queue is empty~");
                            queue.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }

                    Object value = queue.poll();
                    log.info("[Consumer]--Consume element {}", value);
                    queue.notifyAll();
                }
            }

        }

    }

    public static void main(String[] args) {
        for (int i = 0; i < 15; i++) {
            // 创建生产者
            new Thread(new Solution1.Producer()).start();
        }

        // 创建消费者
        new Thread(new Solution1.Consumer()).start();
    }


}
